要素同步 Sample详情
最后更新时间:2019年7月5日
要素同步编辑,即涉及地图某一图层要素的下载、更新、提交操作。首先,用户可以将IGServer服务器上发布的矢量图层要素数据下载到本地数据库中;当服务器上发布的图层要素数据发生变化时,对本地数据库中的图层数据进行更新;当本地数据库中矢量图层要素数据发生变化时,可以将变更数据提交到服务器进行同步。
当用户需要在移动端离线使用IGServer服务器上发布的矢量图层数据时,可以将其图层全部下载或者设置范围和属性条件下载到本地“.mgdb”数据库中。
需要注意的是:下载数据时,要保证程序运行的网络流畅,如果网络速度较慢或者网络情况不佳的话,下载速度会比较慢,也有可能导致下载失败。
要素同步编辑下载,基于数据类型与素筛选条件可以分为以下几种方式,如图所示。
要素同步下载功能实现的关键步骤如图 6 8所示:
1
获取下载数据信息,可通过登录IGServer服务管理器直接查看,也可通过代码方式获取;
NSString *igserverBaseURL = @"http://develop.smaryun.com:6163/igs"; //服务基地址 NSString *layerURL = @"gdbp://MapGisLocal/武汉MKT/sfcls/四级点"; //图层URL
2
设置数据保存位置,要素同步编辑中的下载是下载到已有数据库中。
//数据库在移动设备存储中的路径 NSString *dataBasePath= [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapEdit/武汉MKT.mgdb"]; //创建数据库对象 MGSDataBase *dataBase=[[MGSDataBase alloc] init]; //打开本地路径中的数据库 [dataBase open:dataBasePath];
3
创建下载条件,下载按筛选条件分为全图范围、部分范围和属性条件。
MGSRect rect=MGSRectMake(xMin,yMin, xMax,yMax);
NSString *whereClause=@"Name LIKE '%公园%'";
4
进行数据的下载,首先需要根据下载的数据类型(图层服务或地图服务)、下载的条件选择合适的下载接口,MGSFeatureSync类提供的接口如下所示:
接口 | 说明 |
---|---|
+ (long)downloadAllASyncWithIGServerBaseURL:(NSString*)IGServerBaseURL
dataURL:(NSString*)dataURL database:(MGSDataBase*)database
clsType:(MGSXClsType)clsType clsName:(NSString*)clsName; 参数:服务基地址、图层URL、数据库、要素类型、类名 |
全图下载异步执行 |
+ (long)downloadASyncWithIGServerBaseURL:(NSString*)IGServerBaseURL
dataURL:(NSString*)dataURL extent:(MGSRect)extent
whereClause:(NSString*)whereClause database:(MGSDataBase*)database
clsType:(MGSXClsType)clsType clsName:(NSString*)clsName; 参数:服务基地址、图层URL、范围、属性条件、数据库、要素类型、类名 |
指定范围下载异步执行 |
+ (long)downloadAllASyncWithIGServerBaseURL:(NSString*)IGServerBaseURL
docName:(NSString*)docName mapID:(int)mapID layerID:(int)layerID
database:(MGSDataBase*)database clsType:(MGSXClsType)clsType
clsName:(NSString*)clsName; 参数:服务基地址、地图文档名、地图ID、图层ID、数据库、要素类型、类名 |
全图下载异步执行 |
+ (long)downloadASyncWithIGServerBaseURL:(NSString*)IGServerBaseURL
docName:(NSString*)docName mapID:(int)mapID layerID:(int)layerID
extent:(MGSRect)extent whereClause:(NSString*)whereClause
database:(MGSDataBase*)database clsType:(MGSXClsType)clsType
clsName:(NSString*)clsName; 参数:服务基地址、地图文档名、地图ID、图层ID、范围、属性条件、数据库、要素类型、类名 |
指定范围下载异步执行 |
接口说明:
(1)前两个接口适合于图层服务的数据下载、后两个接口适合地图文档服务类型数据的下载。在此说明图层服务和地图文档服务的区别:
(2)第一个和第三个接口是默认下载图层中全部范围数据的,第二个和第四个接口中可以指定下载的地图范围,以及下载的属性过滤条件。
在明确了接口的作用之后,根据实际情况选择对应的接口下载数据,如果数据为图层服务,可采用如下方法实现:
//图层服务-全图下载(参数:服务基地址、图层URL、数据库、要素类型、类名) long downCode=[MGSFeatureSync downloadAllASyncWithIGServerBaseURL:self.igserverBaseURL dataURL:self.layerURL database:self.dataBase clsType:SFCls clsName:self.clsName]; //clsName为本地数据库中简单要素类名,如“四级点”,一般和下载的图层名保持一致 //图层服务-范围下载(参数:服务基地址、图层URL、范围、属性条件、数据库、要素类型、类名) long downCode=[MGSFeatureSync downloadASyncWithIGServerBaseURL:self.igserverBaseURL dataURL:self.layerURL extent:self.rect whereClause:nil database:self.dataBase clsType:SFCls clsName:self.clsName]; //如果范围和属性条件都设置为空,默认下载全图 //图层服务-属性条件下载(与范围下载采用同一接口) long downCode=[MGSFeatureSync downloadASyncWithIGServerBaseURL:self.igserverBaseURL dataURL:self.layerURL extent:[_mapView.map range] whereClause:self.whereClause database:self.dataBase clsType:SFCls clsName:self.clsName];
如果数据为地图服务,采用如下方法:
//地图服务-全图下载(参数:服务基地址、地图文档名、地图ID、图层ID、数据库、要素类型、类名) long downCode=[MGSFeatureSync downloadAllASyncWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0 layerID:self.layerID database:self.dataBase clsType:SFCls clsName:self.clsName]; //地图服务-范围下载(参数:服务基地址、地图文档名、地图ID、图层ID、范围、属性条件、数据库、要素类型、类名) long downCode=[MGSFeatureSync downloadASyncWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0 layerID:self.layerID extent:self.rect whereClause:nil database:self.dataBase clsType:SFCls clsName:self.clsName]; //如果范围和属性条件都设置为空,默认下载全图 //地图服务-属性条件下载(与范围下载采用同一接口) long downCode=[MGSFeatureSync downloadASyncWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0 layerID:self.layerID extent:[_mapView.map range] whereClause:self.whereClause database:self.dataBase clsType:SFCls clsName:self.clsName];
说明:
(1)所有的下载方法都为静态方法,直接使用类名调用即可。
(2)所有的下载方法都是异步方法,并附带监听,不需要用户开启子线程。
(3)返回结果代表下载编号,可以支持多任务并发执行。
(4)如果下载过程中需要停止,可以调用stopASyncWithSyncCode:方法,同样适用于后续的更新、提交操作。
5
数据下载是一个过程,接口将下载的操作封装在子线程中,属于异步执行。SDK提供了监听方法来不断获取下载的进度、结果信息。
首先需要为ViewController遵守下载进度回调、下载结果回调代理协议,然后为要素同步类设置代理,最后实现其回调函数,获取进度、结果信息。
@interface FeatureSync_ViewController ()<ProgressListener,FinishedListener> //为要素同步设置进度监听:包括下载、更新、提交 [MGSFeatureSync setProgressListener:self]; //为要素同步设置结果监听:包括下载、更新、提交 [MGSFeatureSync setFinishedListener:self];
获取下载进度信息:
//要素同步进度回调(非主线程回调) -(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _downCode) { //判断下载任务编号 NSLog(@"下载任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n下载进度:%.2f%%",_downCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
同时,SDK也提供了下载的结果监听方法:
//要素同步结果回调(非主线程回调) -(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _downCode) { //判断下载任务编号 if (normalSuccessed) { NSLog(@"下载成功!"); } else { NSLog(@"下载失败!"); } } }
6
在数据下载完成后,用户可通过使用Database对象的getXclsInfo方法获取要素类,然后创建矢量图层对象VectorLayer,进行显示。
针对从IGServer服务器上下载的本地数据,当IGServer服务器上的矢量图层发生改变时,如果需要对移动端本地数据进行同步,可以不用再次下载,直接利用更新操作即可。
需要注意:在更新之前,需要先将移动端本地数据库中的要素类和服务器中的图层数据进行捆绑,才能成功进行下一步的更新操作。
要素同步更新功能实现的关键步骤如下图所示:
1
获取IGServer在线数据和已下载待更新数据;
//在线数据:服务基地址、图层URL、地图文档名称 NSString *igserverBaseURL = @"http://develop.smaryun.com:6163/igs"; NSString *layerURL = @"gdbp://MapGisLocal/武汉MKT/sfcls/四级点"; NSString *docName = @"WuHan"; //离线数据 NSString *dataBasePath= [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapEdit/武汉MKT.mgdb"]; //创建数据库对象 MGSDataBase *dataBase=[[MGSDataBase alloc] init]; //打开本地路径中的数据库 [dataBase open:dataBasePath]; //构造简单要素类对象 MGSSFeatureCls *featureCls=[[MGSSFeatureCls alloc] initWithDataBase:dataBase]; //打开要素类 [featureCls openWithName:self.clsName];
2
在进行更新操作之前,需要将离线、在线数据进行捆绑,从而才能知道将什么在线数据更新到移动本地。同样可选择图层服务和地图服务两种方式。
//数据捆绑-图层服务(参数:矢量类对象、地图服务基地址、图层URL) long bind=[MGSFeatureSync bindASync:featureCls IGServerBaseURL:igserverBaseURL dataURL:layerURL]; //数据捆绑-地图服务(参数:矢量类对象、地图服务基地址、地图文档名称、地图ID、图层ID) long bind=[MGSFeatureSync bindASync:featureCls IGServerBaseURL:igserverBaseURL docName:docName mapID:0 layerID:layerID];
3
在准备工作完成后,就可以进行具体的数据更新操作。更新操作同样是异步操作,不需用户开启子线程。
//返回long类型的数值,表示此更新任务的编号 long updateCode=[MGSFeatureSync updateASync:featureCls];
4
与下载操作一样,具有监听器可以监听更新的进度、结果信息,并且调用的接口也一致。
更新进度监听:
//要素同步进度回调(非主线程回调) -(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _updateCode) { //判断更新任务编号 NSLog(@"更新任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n更新进度:%.2f%%",_updateCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
更新结果监听:
//要素同步结果回调(非主线程回调) -(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _updateCode) { //判断更新任务编号 if (normalSuccessed) { NSLog(@"更新成功!"); } else { NSLog(@"更新失败!"); } } }
5
在对离线数据更新完成之后,需要重新读取Database中的数据进行展示才能看到效果。
针对从IGServer服务器上下载的本地数据,如果移动端本地数据库中的矢量图层要素发生改变,例如在移动端进行离线要素的编辑,可以将此图层中所编辑的要素数据提交到IGServer服务器上,实现离线和在线数据的同步。
需要注意:与数据更新一样,在提交数据之前,需要先将移动端本地数据库中的要素类和服务器中的图层数据进行捆绑,才能成功进行下一步的提交操作。
要素同步提交和更新的实现基本类似,功能实现的关键步骤如下:
1
获取IGServer在线数据和已下载待更新数据,方法与更新操作一致。
2
在进行提交操作之前,同样需要将离线、在线数据进行捆绑。
//数据捆绑-图层服务(参数:矢量类对象、地图服务基地址、图层URL) long bind=[MGSFeatureSync bindASync:featureCls IGServerBaseURL:igserverBaseURL dataURL:layerURL]; //数据捆绑-地图服务(参数:矢量类对象、地图服务基地址、地图文档名称、地图ID、图层ID) long bind=[MGSFeatureSync bindASync:featureCls IGServerBaseURL:igserverBaseURL docName:docName mapID:0 layerID:layerID];
3
提交数据。
//返回long类型的数值,表示此提交任务的编号 long commitCode=[MGSFeatureSync commitASync:_featureCls];
4
与下载、更新操作一样,具有监听器可以监听提交的进度、结果信息,并且调用的接口也一致。
提交进度监听:
//要素同步进度回调(非主线程回调) -(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _commitCode) { NSLog(@"提交任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n提交进度:%.2f%%",_commitCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
提交结果监听:
//要素同步结果回调(非主线程回调) -(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _commitCode) { if (normalSuccessed) { NSLog(@"提交成功!"); } else { NSLog(@"提交失败!"); } } }
5
在对离线数据更新完成之后,需要重新读取Database中的数据进行展示才能看到效果。